﻿using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Collections.Concurrent;

namespace LoggerTest.CustomLogger
{
    [ProviderAlias("Custom")]
    public class CustomLoggerProvider : ILoggerProvider
    {
        /// <summary>
        /// 配置选项
        /// </summary>
        private readonly IOptionsMonitor<CustomLoggerOptions> _options;
        /// <summary>
        /// 配置变更令牌
        /// </summary>
        private readonly IDisposable? _optionsReloadToken;
        /// <summary>
        /// 日志字典
        /// </summary>
        private readonly ConcurrentDictionary<string, CustomLogger> _loggers = [];
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="options"></param>
        public CustomLoggerProvider(IOptionsMonitor<CustomLoggerOptions> options)
        {
            _options = options;
            ReloadLoggerOptions(options.CurrentValue);
            _optionsReloadToken = _options.OnChange(ReloadLoggerOptions);
        }
        /// <summary>
        /// 创建日志
        /// </summary>
        /// <param name="categoryName"></param>
        /// <returns></returns>
        public ILogger CreateLogger(string categoryName)
        {
            if (!_loggers.TryGetValue(categoryName, out CustomLogger? value))
            {
                value = _loggers.GetOrAdd(categoryName, new CustomLogger(categoryName, _options.CurrentValue));
            }
            return value;
        }
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _loggers.Clear();
            _optionsReloadToken?.Dispose();
        }
        /// <summary>
        /// 重新加载日志配置
        /// </summary>
        /// <param name="options"></param>
        private void ReloadLoggerOptions(CustomLoggerOptions options)
        {
            foreach (KeyValuePair<string, CustomLogger> logger in _loggers)
            {
                logger.Value.Options = options;
            }
        }
    }
}
